home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 22 / Cream of the Crop 22.iso / os2 / npswp182.zip / NPSWPSWA.CPP < prev    next >
C/C++ Source or Header  |  1995-10-22  |  18KB  |  492 lines

  1. // Standard Window Animation DLL for NPS WPS Enhancer
  2. // Copyright (C) 1995, N.P.S.
  3. // 100 or more columns are necessary to read this file properly
  4.  
  5. #define INCL_PM
  6. #include <os2.h>
  7. #include <memory.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include "npswpswa.h"
  11.  
  12. // to export
  13.  
  14. extern "C" BOOL EXPENTRY SpinFrame(AnimationData *padat);
  15. extern "C" BOOL EXPENTRY VortexFrames(AnimationData *padat);
  16. extern "C" BOOL EXPENTRY ScatterGatherFrames(AnimationData *padat);
  17. extern "C" BOOL EXPENTRY SpikeFrames(AnimationData *padat);
  18. extern "C" BOOL EXPENTRY FireworksFrames(AnimationData *padat);
  19.  
  20. const FIXED Fixed1 = 1 << 16;
  21. static POINTL PointZero = { 0, 0 };
  22. static MATRIXLF Matrix1 = { Fixed1, 0, 0, 0, Fixed1, 0, 0, 0, 1 }; // unit matrix
  23.  
  24. struct DisjointLine
  25. {  POINTL ptStart, ptEnd;
  26. };
  27.  
  28. LONG fixedMul(LONG lMultiplicand, FIXED fMultiplier);
  29. FIXED fixedDiv(LONG lNumerator, LONG lDenominator);
  30. POINTL operator*(const POINTL &point, const MATRIXLF &matrix);
  31. MATRIXLF operator*(const MATRIXLF &matrix1, const MATRIXLF &matrix2);
  32. MATRIXLF mix(const MATRIXLF &matrix1, const MATRIXLF &matrix2, FIXED fMix);
  33. POINTL mix(const POINTL &point1, const POINTL &point2, FIXED fMix);
  34.  
  35. void drawDisjoint(HPS hps, DisjointLine *paDisjointLine, LONG cLines);
  36. LONG setDisjointLine(DisjointLine *pDisjointLine, const POINTL& ptStart, const POINTL &ptEnd);
  37. LONG setDisjointBox(DisjointLine *pDisjointLine,
  38.             const POINTL& ptCenter, const POINTL &ptRelRightTop);
  39.  
  40. inline POINTL operator+(POINTL &point1, POINTL &point2)
  41. {  POINTL pointResult;
  42.    pointResult.x = point1.x + point2.x;
  43.    pointResult.y = point1.y + point2.y;
  44.    return pointResult;
  45. }
  46.  
  47. inline POINTL operator-(POINTL &point1, POINTL &point2)
  48. {  POINTL pointResult;
  49.    pointResult.x = point1.x - point2.x;
  50.    pointResult.y = point1.y - point2.y;
  51.    return pointResult;
  52. }
  53.  
  54. inline MATRIXLF& operator*=(MATRIXLF &matrix1, const MATRIXLF &matrix2)
  55. {  return matrix1 = matrix1 * matrix2;
  56. }
  57.  
  58. BOOL EXPENTRY SpinFrame(AnimationData *padat)
  59. {  if (padat->animCallType == AnimationDraw
  60.        || padat->animCallType == AnimationErase)
  61.    {  POINTL aPtRectangle[4];
  62.       aPtRectangle[1].x = aPtRectangle[0].x = padat->ptRelRightTop.x;
  63.       aPtRectangle[1].y = -(aPtRectangle[0].y = padat->ptRelRightTop.y);
  64.  
  65.       MATRIXLF matrix;
  66.       FIXED afxScale[2];
  67.       afxScale[0] = afxScale[1] = fixedDiv(padat->lStep, padat->cTotalSteps);
  68.       GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale, &PointZero);
  69.       GpiRotate(padat->hps, &matrix, TRANSFORM_ADD,
  70.         fixedDiv(padat->lParameter * (padat->lStep - padat->cTotalSteps),
  71.              padat->cTotalSteps),
  72.         &PointZero);
  73.       aPtRectangle[0] = aPtRectangle[0] * matrix;
  74.       aPtRectangle[1] = aPtRectangle[1] * matrix;
  75.  
  76.       if ((aPtRectangle[0].x != 0 || aPtRectangle[0].y != 0)
  77.       && (aPtRectangle[1].x != 0 || aPtRectangle[1].y != 0))
  78.       {  aPtRectangle[2] = padat->ptCenter + aPtRectangle[0];
  79.      aPtRectangle[3] = padat->ptCenter + aPtRectangle[1];
  80.      aPtRectangle[0] = padat->ptCenter - aPtRectangle[0];
  81.      aPtRectangle[1] = padat->ptCenter - aPtRectangle[1];
  82.      GpiMove(padat->hps, &aPtRectangle[3]);
  83.      GpiPolyLine(padat->hps, 4, aPtRectangle);
  84.       }
  85.    }
  86.  
  87.    return TRUE;
  88. }
  89.  
  90. BOOL EXPENTRY VortexFrames(AnimationData *padat)
  91. {  switch (padat->animCallType)
  92.    {  case AnimationInitialize:
  93.      GpiRotate(padat->hps, (MATRIXLF *)padat->achBuffer, TRANSFORM_REPLACE,
  94.            72 * Fixed1, &padat->ptCenter);
  95.      break;
  96.       case AnimationDraw:
  97.       case AnimationErase:
  98.       {  POINTL ptBoxRel;
  99.      ptBoxRel.x = padat->ptRelRightTop.x * padat->lStep / padat->cTotalSteps;
  100.      ptBoxRel.y = padat->ptRelRightTop.y * padat->lStep / padat->cTotalSteps;
  101.  
  102.      MATRIXLF matrix;
  103.      FIXED afxScale[2];
  104.      afxScale[0] = afxScale[1] = fixedDiv((padat->cTotalSteps - padat->lStep) * 5,
  105.                           padat->cTotalSteps * 3);
  106.      GpiTranslate(padat->hps, &matrix, TRANSFORM_REPLACE, &padat->ptRelRightTop);
  107.      GpiScale(padat->hps, &matrix, TRANSFORM_ADD, afxScale, &padat->ptCenter);
  108.      GpiRotate(padat->hps, &matrix, TRANSFORM_ADD,
  109.            fixedDiv(padat->lParameter * padat->lStep, padat->cTotalSteps),
  110.            &padat->ptCenter);
  111.  
  112.      DisjointLine adjline[5 * 4];
  113.      LONG cLines = 0;
  114.      POINTL ptBoxCenter = padat->ptCenter * matrix;
  115.  
  116.      for (int iLoop = 0; iLoop < 5; iLoop++)
  117.      {  cLines += setDisjointBox(&adjline[cLines], ptBoxCenter, ptBoxRel);
  118.         ptBoxCenter = ptBoxCenter * *(MATRIXLF *)padat->achBuffer;
  119.      }
  120.  
  121.      drawDisjoint(padat->hps, adjline, cLines);
  122.      break;
  123.       }
  124.    }
  125.  
  126.    return TRUE;
  127. }
  128.  
  129. BOOL EXPENTRY ScatterGatherFrames(AnimationData *padat)
  130. {  if (padat->animCallType == AnimationDraw
  131.        || padat->animCallType == AnimationErase)
  132.    {  LONG lDivisor = padat->lParameter;
  133.       POINTL ptBoxRel;
  134.       
  135.       ptBoxRel.x = padat->ptRelRightTop.x * padat->lStep / (padat->cTotalSteps * lDivisor);
  136.       ptBoxRel.y = padat->ptRelRightTop.y * padat->lStep / (padat->cTotalSteps * lDivisor);
  137.  
  138.       MATRIXLF matrix;
  139.       FIXED afxScale[2];
  140.       afxScale[0] = afxScale[1] = fixedDiv(padat->cTotalSteps * 3 - padat->lStep * 2,
  141.                        padat->cTotalSteps);
  142.       GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale, &PointZero);
  143.       GpiTranslate(padat->hps, &matrix, TRANSFORM_ADD, &padat->ptCenter);
  144.  
  145.       DisjointLine adjline[10 * 10 * 4];  // The maximum number of rects is 10 * 10
  146.       LONG cLines = 0;
  147.  
  148.       for (int iRow = 0; iRow < lDivisor; iRow++)
  149.       {  for (int iColumn = 0; iColumn < padat->lParameter; iColumn++)
  150.      {  POINTL ptTileCenter;
  151.         ptTileCenter.x = (iRow * 2 - lDivisor + 1) * padat->ptRelRightTop.x / lDivisor;
  152.         ptTileCenter.y = (iColumn * 2 - lDivisor + 1) * padat->ptRelRightTop.y / lDivisor;
  153.         ptTileCenter = ptTileCenter * matrix;
  154.         cLines += setDisjointBox(&adjline[cLines], ptTileCenter, ptBoxRel);
  155.      }
  156.       }
  157.  
  158.       drawDisjoint(padat->hps, adjline, cLines);
  159.    }
  160.  
  161.    return TRUE;
  162. }
  163.  
  164. BOOL EXPENTRY SpikeFrames(AnimationData *padat)
  165. {  struct SpikeData
  166.    {  POINTL aPtTriangleEnd[16][3], aPtEndCenter[16], aPtTriangleCenter[16];
  167.       MATRIXLF aMatrixCircle[16];
  168.    };
  169.  
  170.    switch (padat->animCallType)
  171.    {  case AnimationInitialize:
  172.       {  LONG xLeft = padat->rectWindow.xLeft,
  173.           xRight = padat->rectWindow.xRight,
  174.           yBottom = padat->rectWindow.yBottom,
  175.           yTop = padat->rectWindow.yTop;
  176.         
  177.      POINTL *paPtTriangle = ((SpikeData *)padat->achBuffer)->aPtTriangleEnd[0],
  178.             *paPtCenter = ((SpikeData *)padat->achBuffer)->aPtEndCenter;
  179.      for (int iIndex = 0; iIndex < 16; iIndex++, paPtTriangle += 3, paPtCenter++)
  180.      {  paPtTriangle[0] = padat->ptCenter;
  181.  
  182.         if (iIndex < 4)
  183.         {  paPtTriangle[1].y = paPtTriangle[2].y = yTop;
  184.            paPtTriangle[1].x = (xLeft * (4 - iIndex) + xRight * iIndex) / 4;
  185.            paPtTriangle[2].x = (xLeft * (3 - iIndex) + xRight * (iIndex + 1)) / 4;
  186.         }
  187.         else if (iIndex < 8)
  188.         {  paPtTriangle[1].x = paPtTriangle[2].x = xRight;
  189.            paPtTriangle[1].y = (yTop * (8 - iIndex) + yBottom * (iIndex - 4)) / 4;
  190.            paPtTriangle[2].y = (yTop * (7 - iIndex) + yBottom * (iIndex - 3)) / 4;
  191.         }
  192.         else if (iIndex < 12)
  193.         {  paPtTriangle[1].y = paPtTriangle[2].y = yBottom;
  194.            paPtTriangle[1].x = (xRight * (12 - iIndex) + xLeft * (iIndex - 8)) / 4;
  195.            paPtTriangle[2].x = (xRight * (11 - iIndex) + xLeft * (iIndex - 7)) / 4;
  196.         }
  197.         else
  198.         {  paPtTriangle[1].x = paPtTriangle[2].x = xLeft;
  199.            paPtTriangle[1].y = (yBottom * (16 - iIndex) + yTop * (iIndex - 12)) / 4;
  200.            paPtTriangle[2].y = (yBottom * (15 - iIndex) + yTop * (iIndex - 11)) / 4;
  201.         }
  202.  
  203.         paPtCenter->x = (paPtTriangle[0].x + paPtTriangle[1].x + paPtTriangle[2].x) / 3;
  204.         paPtCenter->y = (paPtTriangle[0].y + paPtTriangle[1].y + paPtTriangle[2].y) / 3;
  205.      }
  206.  
  207.      paPtCenter = ((SpikeData *)padat->achBuffer)->aPtTriangleCenter;
  208.      POINTL ptTriangleCenter;
  209.      ptTriangleCenter.x = padat->ptCenter.x;
  210.      ptTriangleCenter.y =
  211.         padat->ptCenter.y + (padat->ptRelRightTop.x + padat->ptRelRightTop.y) * 4 / 5;
  212.      
  213.      for (iIndex = 0; iIndex < 16; iIndex++)
  214.      {  MATRIXLF matrix;
  215.         GpiRotate(padat->hps, &matrix, TRANSFORM_REPLACE,
  216.               (33 * Fixed1) + (-22 * Fixed1) * iIndex, &padat->ptCenter);
  217.         paPtCenter[iIndex] = ptTriangleCenter * matrix;
  218.  
  219.         POINTL ptTemp =
  220.            paPtCenter[iIndex] - ((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex];
  221.         GpiTranslate(padat->hps, &((SpikeData *)padat->achBuffer)->aMatrixCircle[iIndex],
  222.              TRANSFORM_REPLACE, &ptTemp);
  223.      }
  224.  
  225.      break;
  226.       }
  227.       case AnimationDraw:
  228.       case AnimationErase:
  229.       {  POINTL aPtTriangle[3];
  230.      DisjointLine adjline[16 * 3];
  231.      int cLines = 0;
  232.      FIXED fixedFactor;
  233.  
  234.      MATRIXLF matrix;
  235.      FIXED afxScale[2];
  236.      afxScale[0] = afxScale[1] = fixedDiv(padat->lStep, padat->cTotalSteps);
  237.  
  238.      if (padat->lStep < padat->cTotalSteps / 2)
  239.      {  fixedFactor = (Fixed1 - fixedDiv(padat->lStep * 2, padat->cTotalSteps))
  240.            * padat->lParameter;
  241.  
  242.         for (int iIndex = 0; iIndex < 16; iIndex++)
  243.         {  GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale,
  244.             &((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex]);
  245.            GpiRotate(padat->hps, &matrix, TRANSFORM_ADD, fixedFactor,
  246.              &((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex]);
  247.            matrix *= ((SpikeData *)padat->achBuffer)->aMatrixCircle[iIndex];
  248.  
  249.            for (int iAngle = 0; iAngle < 3; iAngle++)
  250.            {  aPtTriangle[iAngle] = 
  251.              ((SpikeData *)padat->achBuffer)->aPtTriangleEnd[iIndex][iAngle] * matrix;
  252.            }
  253.  
  254.            for (iAngle = 0; iAngle < 3; iAngle++)
  255.            {  cLines += setDisjointLine(&adjline[cLines], aPtTriangle[iAngle],
  256.                         aPtTriangle[(iAngle + 1) % 3]);
  257.            }
  258.         }
  259.      }
  260.      else
  261.      {  fixedFactor = fixedDiv(padat->lStep * 2 - padat->cTotalSteps, padat->cTotalSteps);
  262.         
  263.         for (int iIndex = 0; iIndex < 16; iIndex++)
  264.         {  GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale,
  265.             &((SpikeData *)padat->achBuffer)->aPtEndCenter[iIndex]);
  266.            matrix *= mix(Matrix1, ((SpikeData *)padat->achBuffer)->aMatrixCircle[iIndex],
  267.                  fixedFactor);
  268.  
  269.            for (int iAngle = 0; iAngle < 3; iAngle++)
  270.            {  aPtTriangle[iAngle] = 
  271.              ((SpikeData *)padat->achBuffer)->aPtTriangleEnd[iIndex][iAngle] * matrix;
  272.            }
  273.  
  274.            for (iAngle = 0; iAngle < 3; iAngle++)
  275.            {  cLines += setDisjointLine(&adjline[cLines], aPtTriangle[iAngle],
  276.                         aPtTriangle[(iAngle + 1) % 3]);
  277.            }
  278.         }
  279.      }
  280.  
  281.      drawDisjoint(padat->hps, adjline, cLines);
  282.      break;
  283.       }
  284.    }
  285.  
  286.    return TRUE;
  287. }
  288.  
  289. BOOL EXPENTRY FireworksFrames(AnimationData *padat)
  290. {  const int NUMBER_OF_RECTS = 10;
  291.  
  292.    struct FireworksData
  293.    {  POINTL aPtCenter[NUMBER_OF_RECTS];
  294.    };
  295.  
  296.    switch (padat->animCallType)
  297.    {  case AnimationInitialize:
  298.       {  POINTL *paPtCenter = ((FireworksData *)padat->achBuffer)->aPtCenter;
  299.      POINTL ptRectCenter;
  300.      ptRectCenter.x = padat->ptCenter.x;
  301.      ptRectCenter.y =
  302.         padat->ptCenter.y + (padat->ptRelRightTop.x + padat->ptRelRightTop.y) * 5 / 3;
  303.      
  304.      for (int iIndex = 0; iIndex < NUMBER_OF_RECTS; iIndex++)
  305.      {  MATRIXLF matrix;
  306.         GpiRotate(padat->hps, &matrix, TRANSFORM_REPLACE,
  307.               iIndex * (360 * Fixed1 / NUMBER_OF_RECTS), &padat->ptCenter);
  308.         paPtCenter[iIndex] = ptRectCenter * matrix;
  309.      }
  310.  
  311.      break;
  312.       }
  313.       case AnimationDraw:
  314.       case AnimationErase:
  315.       {  POINTL ptTemp;
  316.      DisjointLine adjline[NUMBER_OF_RECTS * 4];
  317.      int cLines = 0;
  318.      FIXED fixedFactor = fixedDiv(padat->lStep, padat->cTotalSteps);
  319.  
  320.      MATRIXLF matrix;
  321.      FIXED afxScale[2];
  322.      afxScale[0] = afxScale[1] = fixedFactor;
  323.  
  324.      POINTL aPtRect[4], aPtTemp[4];
  325.      aPtRect[0].x = aPtRect[3].x = -padat->ptRelRightTop.x;
  326.      aPtRect[1].x = aPtRect[2].x = padat->ptRelRightTop.x;
  327.      aPtRect[0].y = aPtRect[1].y = padat->ptRelRightTop.y;
  328.      aPtRect[2].y = aPtRect[3].y = -padat->ptRelRightTop.y;
  329.  
  330.      for (int iIndex = 0; iIndex < NUMBER_OF_RECTS; iIndex++)
  331.      {  GpiScale(padat->hps, &matrix, TRANSFORM_REPLACE, afxScale, &PointZero);
  332.         GpiRotate(padat->hps, &matrix, TRANSFORM_ADD,
  333.               (Fixed1 - fixedFactor) * padat->lParameter, &PointZero);
  334.         POINTL ptTemp;
  335.         ptTemp = mix(padat->ptCenter, ((FireworksData *)padat->achBuffer)->aPtCenter[iIndex],
  336.              fixedFactor);
  337.         GpiTranslate(padat->hps, &matrix, TRANSFORM_ADD, &ptTemp);
  338.       
  339.         for (int iAngle = 0; iAngle < 4; iAngle++)
  340.         {  aPtTemp[iAngle] = aPtRect[iAngle] * matrix;
  341.         }
  342.       
  343.         for (iAngle = 0; iAngle < 4; iAngle++)
  344.         {  cLines += setDisjointLine(&adjline[cLines], aPtTemp[iAngle],
  345.                      aPtTemp[(iAngle + 1) % 4]);
  346.         }
  347.      }
  348.  
  349.      drawDisjoint(padat->hps, adjline, cLines);
  350.      break;
  351.       }
  352.    }
  353.  
  354.    return TRUE;
  355. }
  356.  
  357. // drawing functions
  358.  
  359. void drawDisjoint(HPS hps, DisjointLine *paDisjointLine, LONG cLines)
  360. {  // draw disjoint lines
  361.    // GpiPolyLineDisjoint is much faster than a few GpiLine's
  362.  
  363.    if (cLines > 0) GpiPolyLineDisjoint(hps, cLines * 2, (PPOINTL)paDisjointLine);
  364. }
  365.  
  366. LONG setDisjointLine(DisjointLine *pDisjointLine, const POINTL& ptStart, const POINTL &ptEnd)
  367. {  // set the line data between ptStart and ptEnd
  368.    // return 1 if the line is valid, 0 if not
  369.  
  370.    if (ptStart.x == ptEnd.x && ptStart.y == ptEnd.y) return 0;
  371.    else
  372.    {  pDisjointLine->ptStart = ptStart;
  373.       pDisjointLine->ptEnd = ptEnd;
  374.       return 1;  // 1 struct was set
  375.    }
  376. }
  377.  
  378. LONG setDisjointBox(DisjointLine *pDisjointLine,
  379.             const POINTL& ptCenter, const POINTL &ptRelRightTop)
  380. {  // set the line data of the rectangle
  381.    // return the number of valid lines, 0 means there's no valid line
  382.  
  383.    POINTL aPtRectangle[4];
  384.  
  385.    for (int iIndex = 0; iIndex < 4; iIndex++)
  386.    {  aPtRectangle[iIndex].x =
  387.      ptCenter.x + (iIndex == 0 || iIndex == 3 ? -ptRelRightTop.x : ptRelRightTop.x);
  388.       aPtRectangle[iIndex].y = ptCenter.y + (iIndex <= 1 ? -ptRelRightTop.y : ptRelRightTop.y);
  389.    }
  390.  
  391.    LONG cLines = 0;
  392.    for (iIndex = 0; iIndex < 4; iIndex++)
  393.    {  if (setDisjointLine(pDisjointLine, aPtRectangle[iIndex], aPtRectangle[(iIndex + 1) % 4]))
  394.       {  pDisjointLine++;
  395.      cLines++;
  396.       }
  397.    }
  398.  
  399.    return cLines;
  400. }
  401.  
  402. // helper functions for FIXED etc.
  403.  
  404. LONG fixedMul(LONG lMultiplicand, FIXED fxMultiplier)
  405. {  // returns lMultiplicand * fxMultiplier as a LONG
  406.    // also returns a FIXED if lMultiplicand is a FIXED
  407.  
  408.    return lMultiplicand * (fxMultiplier >> 16) 
  409.       + (lMultiplicand >> 16) * (fxMultiplier & 0xffff)
  410.      + ((ULONG)((lMultiplicand & 0xffff) * (fxMultiplier & 0xffff)) >> 16);
  411. }
  412.  
  413. FIXED fixedDiv(LONG lNumerator, LONG lDenominator)
  414. {  // returns lNumerator / lDenominator as a FIXED
  415.    // also works well for 2 FIXED's
  416.  
  417.    if (lNumerator == 0 || lDenominator == 0) return 0;
  418.  
  419.    LONG lSignBit = (lNumerator ^ lDenominator) >> (sizeof(LONG) * 8 - 1);
  420.    lNumerator = abs(lNumerator);
  421.    lDenominator = abs(lDenominator);
  422.  
  423.    int cShiftRemain = sizeof(SHORT) * 8;
  424.    while ((lDenominator & 1) == 0 && cShiftRemain > 0)
  425.    {  lDenominator >>= 1;
  426.       cShiftRemain--;
  427.    }
  428.    
  429.    ULONG ulQuotient = 0, ulTemp;
  430.  
  431.    do
  432.    {  while ((lNumerator & 0x80000000) == 0 && cShiftRemain > 0)
  433.       {  lNumerator <<= 1;
  434.      cShiftRemain--;
  435.       }
  436.  
  437.       ulTemp = (ULONG)lNumerator / (ULONG)lDenominator;
  438.       lNumerator -= ulTemp * lDenominator;
  439.       ulQuotient += ulTemp << cShiftRemain;
  440.  
  441.    } while (lNumerator != 0 && cShiftRemain > 0);
  442.  
  443.    return (ulQuotient ^ lSignBit) - lSignBit;  /* reverse sign if lSignBit = -1 */
  444. }
  445.  
  446. POINTL operator*(const POINTL &point, const MATRIXLF &matrix)
  447. {  // returns POINTL transformed by MATRIXLF
  448.  
  449.    POINTL pointResult;
  450.    pointResult.x = fixedMul(point.x, matrix.fxM11) + fixedMul(point.y, matrix.fxM21) + matrix.lM31;
  451.    pointResult.y = fixedMul(point.x, matrix.fxM12) + fixedMul(point.y, matrix.fxM22) + matrix.lM32;
  452.    return pointResult;
  453. }   
  454.  
  455. POINTL mix(const POINTL &pointSource1, const POINTL &pointSource2, FIXED fMix)
  456. {  // mix 2 POINTL's according to FIXED
  457.  
  458.    POINTL pointResult;
  459.    pointResult.x = fixedMul(pointSource1.x, fMix) + fixedMul(pointSource2.x, Fixed1 - fMix);
  460.    pointResult.y = fixedMul(pointSource1.y, fMix) + fixedMul(pointSource2.y, Fixed1 - fMix);
  461.    return pointResult;
  462. }
  463.  
  464. MATRIXLF operator*(const MATRIXLF &mtx1, const MATRIXLF &mtx2)
  465. {  // returns product of 2 MATRIXLF's
  466.  
  467.    MATRIXLF mtxProduct;
  468.    mtxProduct.fxM11 = fixedMul(mtx1.fxM11, mtx2.fxM11) + fixedMul(mtx1.fxM12, mtx2.fxM21);
  469.    mtxProduct.fxM12 = fixedMul(mtx1.fxM11, mtx2.fxM12) + fixedMul(mtx1.fxM12, mtx2.fxM22);
  470.    mtxProduct.lM13 = 0;
  471.    mtxProduct.fxM21 = fixedMul(mtx1.fxM21, mtx2.fxM11) + fixedMul(mtx1.fxM22, mtx2.fxM21);
  472.    mtxProduct.fxM22 = fixedMul(mtx1.fxM21, mtx2.fxM12) + fixedMul(mtx1.fxM22, mtx2.fxM22);
  473.    mtxProduct.lM23 = 0;
  474.    mtxProduct.lM31 = fixedMul(mtx1.lM31, mtx2.fxM11) + fixedMul(mtx1.lM32, mtx2.fxM21) + mtx2.lM31;
  475.    mtxProduct.lM32 = fixedMul(mtx1.lM31, mtx2.fxM12) + fixedMul(mtx1.lM32, mtx2.fxM22) + mtx2.lM32;
  476.    mtxProduct.lM33 = 1;
  477.    return mtxProduct;
  478. }
  479.  
  480. MATRIXLF mix(const MATRIXLF &matrix1, const MATRIXLF &matrix2, FIXED fMix)
  481. {  // mix 2 MATRIXLF's according to FIXED
  482.  
  483.    MATRIXLF matrixResult;
  484.    for (int iIndex = 0; iIndex < 9; iIndex++)
  485.    {  ((PLONG)&matrixResult)[iIndex] =
  486.      fixedMul(((PLONG)&matrix1)[iIndex], fMix)
  487.         + fixedMul(((PLONG)&matrix2)[iIndex], Fixed1 - fMix);
  488.    }
  489.  
  490.    return matrixResult;
  491. }
  492.